﻿using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.Transforms;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Criss.Sentiments
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("情感分析多类型");

            MLContext mlContext = new MLContext();

            var list = new List<SentimentData>();
            list.Add(new SentimentData { SentimentText = "哈哈，今天捡到一块钱真是有个小惊喜。", LabelText = "喜" });
            list.Add(new SentimentData { SentimentText = "草你妈，小心老子砍死你", LabelText = "怒" });
            list.Add(new SentimentData { SentimentText = "哈哈，今天玩的真高兴", LabelText = "乐" });
            list.Add(new SentimentData { SentimentText = "哎，倒霉透顶了，有掉了几根头发", LabelText = "哀" });
            list.Add(new SentimentData { SentimentText = "哈哈，今天玩的真高兴", LabelText = "乐" });
            list.Add(new SentimentData { SentimentText = "死一边去", LabelText = "死了" });

            var dataView = mlContext.Data.LoadFromEnumerable(list); //创建培训数据


            var pipeline = mlContext.Transforms.Conversion.MapValueToKey(inputColumnName: "LabelText", outputColumnName: "Label", keyOrdinality: ValueToKeyMappingEstimator.KeyOrdinality.ByValue) //将LabelText 转换为 Label分析结果数据
              .Append(mlContext.Transforms.Text.FeaturizeText(outputColumnName: "Features", inputColumnName: nameof(SentimentData.SentimentText)))//将SentimentText 标志成 分析数据列
              .AppendCacheCheckpoint(mlContext); //缓存数据

            //.Append(_mlContext.Transforms.Concatenate("Features", "TitleFeaturized", "DescriptionFeaturized")) 这个可以分析多类列
           
            var trainingPipeline =
                pipeline.Append(mlContext.MulticlassClassification.Trainers.SdcaMaximumEntropy(labelColumnName: "Label", featureColumnName: "Features",l1Regularization:0.8f,l2Regularization:0.6f)) //指定分析算法，分析列，结果列
                .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabels", "PredictedLabel")); //结果转换类型绑定到列 PredictedLabel


            // 训练模型
            var trainedModel = trainingPipeline.Fit(dataView);

            // 评估模型
            //  var predictions = trainedModel.Transform(dataView);
            //var metrics = mlContext.MulticlassClassification.Evaluate(data: predictions, labelColumnName: "Label", scoreColumnName: "Score");
            //var name = new System.IO.MemoryStream();
            //mlContext.Model.Save(trainedModel, dataView.Schema, name); //这是保存到内存流
            //var newTrainedModel = mlContext.Model.Load(name, out DataViewSchema ddd);//这里读取出来
            //使用模型

            //  var metrics = mlContext.MulticlassClassification.Evaluate(predictions, "Label", "Score");
           
            var predEngine = mlContext.Model.CreatePredictionEngine<SentimentData, SentimentPrediction>(trainedModel); //创建模型


            //engine.OutputSchema[nameof(IrisPrediction.Score)].Annotations.GetValue(AnnotationUtils.Kinds.TrainingLabelValues, ref originalLabels);获取全部分类

            VBuffer<ReadOnlyMemory<char>> keys = new VBuffer<ReadOnlyMemory<char>>();  ///获取全部分类
            predEngine.OutputSchema["PredictedLabel"].GetKeyValues(ref keys); //PredictedLabel 这个可以获取这个操作完以后的列
            var resultprediction = predEngine.Predict(new SentimentData { SentimentText = "哈哈，捡到钱了开心" });

            for (int i = 0; i < resultprediction.Score.Count(); i++)
            {
                Console.Write($"{keys.GetItemOrDefault(i) }:{ resultprediction.Score[i]} "); //输出全部匹配项
            }
            Console.WriteLine($"最终结果:{resultprediction.Prediction}");

            //resultprediction = predEngine.Predict(new SentimentData { SentimentText = "哎，丢了钱了倒霉" });
            //Console.WriteLine(string.Join("_", resultprediction.Score) + "-----------------------" + resultprediction.Prediction);
            //resultprediction = predEngine.Predict(new SentimentData { SentimentText = "草，你敢打我，我弄死你" });
            //Console.WriteLine(string.Join("_", resultprediction.Score) + "-----------------------" + resultprediction.Prediction);

            Console.ReadKey();

        }
    }
}
